/**
 *
 * @param table {Table}
 * @param auth {boolean} 接口是否需要鉴权
 * @param uninstall {boolean} 是否在生成代码时注释该方法，用于备用
 * @returns {string}
 */
const mapByIds = (table, auth = false, uninstall = false) => {
  const {
    idType,
    comment,
    isJpaModel,
    names: {TabName}
  } = table
  return `// <-
    /**
     * ${comment} 按 ID 批量查询，以 id 为 key 返回map
     *
     * @param ids   {@link ${idType}} 数据ID
     * @return Map<${idType}, ${TabName}> Map 对象集合
     */
    ${isJpaModel ? 'default' : 'public'} Map<${idType}, ${TabName}> mapByIds(final Collection<${idType}> ids) {
        return findAllById(Sets.newHashSet(ids))
                .stream()
                .collect(Collectors.toMap(${TabName}::getId, ${TabName}::cloneObject));
    }
    /**
     * ${comment} 按 ID 批量查询 id + 指定字段，返回 map ， id 为 key ， 指定字段为 value 
     *
     * @param ids   Set<${idType}> 数据ID
     * @param exp   {@link Q${TabName}} 指定单个字段
     * @return Map<${idType}, R> Map 对象集合
     */
    ${isJpaModel ? 'default' : 'public'} <R> Map<${idType}, R> mapByIds(final Collection<${idType}> ids, final Expression<R> exp) {
        final Map<${idType}, R> map = new HashMap<>(ids.size());
        getQueryFactory()
                .select(table.id, exp)
                .from(table)
                .where(table.id.in(Sets.newHashSet(ids)))
                .fetch()
                .forEach(tuple -> {
                    if (Objects.nonNull(tuple.get(exp))) {
                        map.put(tuple.get(table.id), tuple.get(exp));
                    }
                });
        return map;
    }
    /**
     * ${comment} 按 ID 批量查询 id + 指定字段，返回 map ， id 为 key ， 指定字段投影到 {@link ${TabName}}
     *
     * @param ids   {@link Set<${idType}>} 数据ID
     * @param exps  {@link Expression} 指定多个字段
     * @return Map<${idType}, ${TabName}> Map 对象集合
     */
    ${isJpaModel ? 'default' : 'public'} Map<${idType}, ${TabName}> mapByIds(final Collection<${idType}> ids, final Expression<?>... exps) {
        return getQueryFactory()
                //.select(Projections.bean(${TabName}.class, ObjectArrays.concat(table.id, exps))) // 如果 exps 带了 id 这里再加一个 id 查询会报错 ：  Multiple entries with same key
                .select(Projections.bean(${TabName}.class, exps))
                .from(table)
                .where(table.id.in(Sets.newHashSet(ids)))
                .fetch()
                .stream()
                .collect(Collectors.toMap(${TabName}::getId, row -> row));
    }
    /**
     * ${comment} 按 ID 批量查询 id + 指定字段，返回 map ， id 为 key ， 指定字段投影到 Class<R>
     *
     * @param ids  {@link Set<${idType}>} 数据ID
     * @param exps {@link Expression} 指定多个字段
     * @return Map<${idType}, R> Map 对象集合
     */
    ${isJpaModel ? 'default' : 'public'} <R> Map<${idType}, R> mapByIds(final Collection<${idType}> ids, final Class<R> clazz, final Expression<?>... exps) {
        return getQueryFactory()
                //.select(table.id, Projections.bean(clazz, ObjectArrays.concat(table.id, exps))) //  如果 exps 带了 id 这里再加一个 id 查询会报错 ：  Multiple entries with same key
                .select(table.id, Projections.bean(clazz, exps))
                .from(table)
                .where(table.id.in(Sets.newHashSet(ids)))
                .fetch()
                .stream()
                .collect(Collectors.toMap(tuple -> tuple.get(table.id), tuple -> Objects.requireNonNull(tuple.get(1, clazz))));
    }
`.split('\n')
    .map(row => (uninstall ? '//' : '') + row)
    .join('\n')
}
export const mapByIdsOpenInstall = table => mapByIds(table)
export const mapByIdsOpenUninstall = table => mapByIds(table, false, true)

export const mapByIdsAuthInstall = table => mapByIds(table, true, false)
export const mapByIdsAuthUninstall = table => mapByIds(table, true, true)
